/****

    activequant - activestocks.eu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

	
	contact  : contact@activestocks.eu
    homepage : http://www.activestocks.eu

 ****/
package org.activequant.container.report;

import org.activequant.core.domainmodel.account.Account;
import org.activequant.core.domainmodel.account.BalanceBook;
import org.activequant.core.domainmodel.account.BalanceEntry;
import org.activequant.core.domainmodel.account.Order;

/**
 * creates a report(AccountReport) from an account(Account). <br/>
 * <b>History:</b><br>
 * - [23.05.2007] Created (Ulrich Staudinger)<br>
 * - [09.06.2007] moved to new account model (Ulrich Staudinger)<br>
 * - [22.02.2008] Refactoring reporting API (Erik Nijkamp)<br>
 * 
 * 
 * @author Ulrich Staudinger
 */
public class AccountReportGenerator {
	/**
	 * an empty AccountReportGenerator constructor
	 */
	public AccountReportGenerator() {

	}
	/**
	 * returns the hit rate calculated from the BalanceEntry-ies of the given balance(BalanceBook)<br/>
	 * <strong>hit rate</strong> = profitable entries(entry.value>0) / total(profits and losses, but no 0's)
	 * @param balance
	 * @return
	 */
	public double getHitRate(BalanceBook balance) {
		double total = 0;
		double correct = 0;
		for (BalanceEntry entry : balance.getBalanceEntries()) {
			if (entry.getValue() > 0) {
				correct++;
				total++;
			} else if (entry.getValue() < 0) {
				total++;
			}
		}
		if (total != 0) {
			return correct / total;
		}
		return Double.NaN;
	}
	/**
	 * returns a String describing the BalanceEntry-ies in the given balance(BalanceBook), in the form:
	 * "${entry1.timeStamp} : ${entry1.value}\n${entry2.timeStamp} : ${entry2.value}\n.......${entryN.timeStamp} : ${entryN.value}\n"
	 * @param balance
	 * @return
	 */
	public String getBalanceDump(BalanceBook balance) {
		StringBuilder s = new StringBuilder();
		for (BalanceEntry entry : balance.getBalanceEntries()) {
			s.append(entry.getTimeStamp());
			s.append(" : ");
			s.append(entry.getValue());
			s.append("\n");
		}
		return s.toString();
	}
	/**
	 * returns a String describing each of the given orders(Order[]) separated by a new line character ("\n")
	 * @param orders
	 * @return
	 */
	public String getOrderDump(Order[] orders) {
		StringBuilder s = new StringBuilder();
		for (Order order : orders) {
			s.append(order.toString());
			s.append("\n");
		}
		return s.toString();
	}
	/**
	 * returns an AccountReport(IReport implementation) for the given account(Account).<br/>
	 * This is where the report calculations should happen but these are commented out now.
	 * @param account
	 * @return
	 */
	public IReport generateReport(Account account) {
		AccountReport report = new AccountReport(account);

		// compute some statistics ...

		/*
		 * TODO restore (en) report.getReportValues().put("Holder",
		 * account.getHolder()); report.getReportValues().put("Biggest gain",
		 * account.getBalance().getBiggestGain());
		 * report.getReportValues().put("Biggest loss",
		 * account.getBalance().getBiggestLoss());
		 * report.getReportValues().put("Gain", account.getCurrentBalance());
		 * report.getReportValues().put("Orders placed",
		 * account.getOrders().length);
		 * report.getReportValues().put("Account Balance",
		 * getBalanceDump(account.getBalance()));
		 * report.getReportValues().put("Hitrate",
		 * getHitRate(account.getBalance()));
		 * report.getReportValues().put("Orders",
		 * getOrderDump(account.getOrders()));
		 */

		return report;
	}
}
